package com.ds.lens.data.controller;

import com.ds.lens.data.common.asserts.Asserts;
import com.ds.lens.data.common.constant.Constants;
import com.ds.lens.data.security.LoginService;
import com.ds.lens.data.service.LensUserService;
import com.ds.lens.data.vo.BaseOutVO;
import com.ds.lens.data.vo.enums.VoMessageEnum;
import com.ds.lens.data.vo.factory.VOFactory;
import com.ds.lens.data.vo.in.LoginUserInVO;
import com.ds.lens.data.vo.in.v2.user.LensUserInVO;
import com.ds.lens.data.vo.out.LoginUserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import static com.ds.lens.data.security.SecuritytConstants.LOGIN_FAIL;

/**
 * @author Gerald Kou
 * @date 2019-05-09
 */
@Slf4j
@RestController
@Api(value = "Application Access controller", description = "服务访问权限认证")
@RequestMapping(produces = {"application/json;charset=UTF-8"})
public class AuthController {
    @Autowired
    private LoginService loginService;

    @Autowired
    private LensUserService lensUserService;

    /**
     * SSO login
     *
     * @param ticket ticket
     * @return BaseOutVO object
     */
    @ApiOperation(value = "SSO Login")
    @GetMapping(value = "/auth/sso/login")
    public BaseOutVO ssoLogin(@RequestParam(value = "ticket") String ticket) {
        LoginUserVO user = loginService.ssoLogin(ticket.trim());
        if (null == user) {
            return VOFactory.getBaseOutVO(VoMessageEnum.FAILED.getCode(), LOGIN_FAIL);
        }
        return VOFactory.getSuccessBaseOutVO(user);
    }

    /**
     * Lens login.
     *
     * @param inVO    inVO
     * @param request request
     * @return BaseOutVO object
     */
    @ApiOperation(value = " Login")
    @PostMapping(value = "/auth/login")
    public BaseOutVO lensLogin(@RequestBody @Valid LoginUserInVO inVO, HttpServletRequest request) {

        LoginUserVO user = loginService.lensLogin(inVO.getUserName(), inVO.getPassword(), request);
        if (null == user) {
            return VOFactory.getBaseOutVO(VoMessageEnum.FAILED.getCode(), LOGIN_FAIL);
        }
        return VOFactory.getSuccessBaseOutVO(user);
    }

    /**
     * Lens logout.
     *
     * @param request request
     * @return BaseOutVO object
     */
    @ApiOperation(value = " Logout")
    @GetMapping(value = "/auth/logout")
    public BaseOutVO lensLogout(HttpServletRequest request) {

        loginService.lensLogout(request);
        return VOFactory.getSuccessBaseOutVO();
    }

    /**
     * Lens register.
     *
     * @param inVO inVO
     * @return BaseOutVO object
     */
    @ApiOperation(value = " register")
    @PostMapping(value = "/auth/register")
    public BaseOutVO lensRegister(@RequestBody @Valid LensUserInVO inVO) {

        lensUserService.lensRegister(inVO);
        return VOFactory.getSuccessBaseOutVO();
    }

    /**
     * Forget password.
     *
     * @param inVO inVO
     * @return BaseOutVO object
     */
    @ApiOperation(value = " Forget password")
    @PostMapping(value = "/auth/forget/password")
    public BaseOutVO forgetPassword(@RequestBody @Valid LensUserInVO inVO) {

        lensUserService.forgetPassword(inVO.getParam());
        return VOFactory.getSuccessBaseOutVO();
    }

    /**
     * Users themselves change the password by forgetting the password.
     *
     * @param inVO inVO
     * @return BaseOutVO object
     */
    @ApiOperation(value = " Reset password")
    @PostMapping(value = "/auth/reset/password")
    public BaseOutVO resetPassword(@RequestBody @Valid LensUserInVO inVO) {

        lensUserService.resetPassword(inVO.getNewPassword(), inVO.getToken());
        return VOFactory.getSuccessBaseOutVO();
    }

    /**
     * Verify that the user name exists.
     *
     * @param inVO inVO
     * @return BaseOutVO object
     */
    @ApiOperation(value = "check username")
    @PostMapping(value = "/lens/check/username")
    public BaseOutVO checkUserName(@RequestBody @Valid LensUserInVO inVO) {

        Asserts.assertFalse(lensUserService.userNameExisted(inVO.getUserName()), Constants.ErrorCode.USERNAME_EXIST);
        return VOFactory.getSuccessBaseOutVO();
    }

    /**
     * Verify email exists.
     *
     * @param inVO inVO
     * @return BaseOutVO object
     */
    @ApiOperation(value = "check email")
    @PostMapping(value = "/lens/check/email")
    public BaseOutVO checkEmail(@RequestBody @Valid LensUserInVO inVO) {
        Asserts.assertFalse(lensUserService.emailExisted(inVO.getEmail()), Constants.ErrorCode.EMAIL_EXIST);

        return VOFactory.getSuccessBaseOutVO();
    }

}
